package jp.co.toshiba.ffsa.service.csas;

import java.sql.Timestamp;
import java.util.Calendar;

import javax.annotation.Resource;

import jp.co.toshiba.ffsa.common.MakeHash;
import jp.co.toshiba.ffsa.common.Validation;
import jp.co.toshiba.ffsa.dto.LoginDto;
import jp.co.toshiba.ffsa.entity.User;
import jp.co.toshiba.ffsa.mail.SendMaiMail;
import jp.co.toshiba.ffsa.service.common.ConstantValue;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.where.ComplexWhere;
import org.seasar.extension.jdbc.where.SimpleWhere;
import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.mai.mail.MailAddress;
import org.seasar.struts.util.MessageResourcesUtil;

import com.ozacc.mail.MailSendException;


/**
 *ID入力Serviceクラス
 * @author (NPC)
 */
public class Csas503Service {
    /** 新パスワード */
    private String newPassword;

    @Resource
    protected LoginDto loginDto;

    /** エラーコード */
    private String errorCode;
    /** userID */
    private String userID;

    
    /**
     * パスワードの入力チェックを行う
     * @return
     * @throws Exception
     */
    public boolean checkInputPassword(String strUserID) throws Exception{
        try{
            if(!this.checkUserPassword(strUserID)){
                // パスワード履歴情報ある場合
                this.errorCode = "errors.password";
                return false;
            }
            if(!this.passwordCheck()){
                // 数字だけか英字だけの場合
                this.errorCode = "errors.password_both_letter";
                return false;
            }
            if(!this.pwdEaCheck()){
                // の場合
                this.errorCode = "errors.password_duplicate_id";
                return false;
            }
       }catch(Exception e){
            throw e;
        }
        return true;
    }

    /**
     * パスワード履歴情報件数取得
     * @param newPassword 新しいパスワード
     * @return successFlag 検索パスワードが履歴と重複チェック
     * @throws Exception エラー
     */
    public boolean checkUserPassword(String strUserID)  throws Exception{
        // 検索パスワードが履歴と重複チェック
        boolean successFlag = false;
        // S2Container初期化
        SingletonS2ContainerFactory.init();
        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);
        // 入力されたパスワードでユーザー情報を検索
        // 検索条件
        try{
        SimpleWhere swh = new SimpleWhere().eq("userId", strUserID)
                                           .eq("deleteFlag", "0")
                                           ;
        ComplexWhere cwh = new ComplexWhere().eq("password", MakeHash.getSha256HashCode(this.newPassword))
                                             .or()
                                             .eq("passwordHistroty1", MakeHash.getSha256HashCode(this.newPassword))
                                             .or()
                                             .eq("passwordHistroty2", MakeHash.getSha256HashCode(this.newPassword))
                                             .or()
                                             .eq("passwordHistroty3", MakeHash.getSha256HashCode(this.newPassword))
                                             ;
        // 一覧取得
        User user = jdbcManager.from(User.class)
                               .where(swh, cwh)
                               .getSingleResult()
                               ;
        if(user != null){
            // パスワードが履歴と重複
            successFlag = false;
        }else{
            // パスワードが履歴と一致しないこと確認
            successFlag = true;
        }
        return successFlag;
        }catch(Exception e){
            throw e;
        }
    }

    /**
     * ユーザ情報取得
     * @param userId ユーザID
     * @return user
     * @throws Exception エラー
     */
    public User getUser(String userId)  throws Exception{

        // S2Container初期化
        SingletonS2ContainerFactory.init();

        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);

        try{
            // 検索条件
            SimpleWhere swh = new SimpleWhere().eq("userId", userId)
                                               .eq("deleteFlag", "0")
                                               ;

            // ユーザ情報取得
            User user = jdbcManager.from(User.class)
                                   .where(swh)
                                   .getSingleResult()
                                   ;

            return user;

        }catch(Exception e){
            throw e;
        }
    }

    /**
     * パスワードのチェック処理
     * 英字だけと数字だけの場合NG
     * @throws Exception
     */
    public boolean passwordCheck() throws Exception{

        try{
            //パスワードが半角数字のみの場合または半角アルファベットのみの場合
            if(newPassword.matches("^[0-9]+$")){return false;}
            if(newPassword.matches("^[a-z]+$")){return false;}
            if(newPassword.matches("^[A-Z]+$")){return false;}
        }catch(Exception e){
            throw e;
        }
        return true;
    }
    /**
     * パスワードのチェック処理
     * メールアドレスを含むのはNG
     * @throws Exception
     */
    public boolean pwdEaCheck() throws Exception{
        boolean passwordCheck;
        try{
            //パスワードと同じ文字がメールアドレスに含れるかチェック
            Validation validation = new Validation();
            String emailAddress = getUser();

            passwordCheck = validation.passwordCheck(emailAddress, newPassword);
        }catch(Exception e){
            throw e;
        }
        return passwordCheck;
    }

    /**
     * newパスワード更新
     * @param user_id ユーザーID
     * @return successFlag 更新チェック
     * @throws Exception
     */
    public boolean updateNewPasswordByUserId(String user_id) throws Exception{
        // 更新チェック
        boolean successFlag = false;
        // S2Container初期化
        SingletonS2ContainerFactory.init();
        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);
        try {
            // ユーザ情報取得
            User user = getUser(user_id);

            // 当日取得
            Calendar cal = Calendar.getInstance();

            // プロパティの値を変更
            user.passwordHistroty3 = user.passwordHistroty2;
            user.passwordHistroty2 = user.passwordHistroty1;
            user.passwordHistroty1 = user.password;
            user.password          = MakeHash.getSha256HashCode(this.newPassword);
            user.passwordFlag      = "1";
            user.passwordUpdateAt  = new Timestamp(cal.getTime().getTime());
            user.loginErrorCount   = 0;
            user.loginErrorAt      = null;
            user.updatedAt         = new Timestamp(cal.getTime().getTime());
            user.updatedBy         = user.userID;

            // 更新
            jdbcManager.update(user).includes("password"
                                    ,"passwordHistroty1"
                                    ,"passwordHistroty2"
                                    ,"passwordHistroty3"
                                    ,"passwordFlag"
                                    ,"passwordUpdateAt"
                                    ,"loginErrorCount"
                                    ,"loginErrorAt"
                                    ,"updatedAt"
                                    ,"updatedBy"
                                    ).execute()
                                    ;
            successFlag = true;
        } catch (Exception e) {
            successFlag = false;
            throw e;
        }
        return successFlag;
    }

    /**
     * メール送信処理
     * @return 処理結果
     * @throws Exception エラー
     */
    public Boolean mailSend( ) throws Exception {
        boolean successFlag = false;
        try {

            // メール情報をセット
            SendMaiMail sendMaiMail = new SendMaiMail();

            // 送信元メールアドレス(From)
            String mailAddressFrom = MessageResourcesUtil.getMessage("mail_address_from");
            sendMaiMail.setMailAddressFrom(mailAddressFrom);

            // 送信先メールアドレス(To)
            String emailAddress = "";
            
            emailAddress = getUser();
            
            MailAddress[] sendMailAddressTo = new MailAddress[1];
            sendMailAddressTo[0] = new MailAddress(emailAddress,"");

            sendMaiMail.setMailAddressTo(sendMailAddressTo);

            sendMaiMail.setReplacementSubject("");
            // 送信
            successFlag = sendMaiMail.sendMail(ConstantValue.pwdUpdMail);

            if(!successFlag){
                this.errorCode = "csas503.902";
                return false;
            }

        }catch(MailSendException m){
            return false;
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }
        return true;

    }

    /**
     * ユーザーメールアドレス取得処理
     * @throws Exception
     */
    public String getUser() throws Exception{
    	
    	String emailAddress = "";
        // S2Container初期化
        SingletonS2ContainerFactory.init();

        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);
        try{
            // 検索条件
            SimpleWhere swh = new SimpleWhere().eq("userID", this.userID)
                                               .eq("deleteFlag", "0");

            // 一覧取得
            User user= jdbcManager.from(User.class)
                                     .where(swh)
                                     .getSingleResult()
                                     ;
            if(user != null){
            	emailAddress = user.mailAddress;
            }

        }catch(Exception e){
            throw e;
        }
        
        return emailAddress;
    }

    /**
     * ユーザーIDをセットする
     * @param userId
     */
    public void setUserId(String userId){this.userID = userId;}    /**
     * 新しいパスワードをセットする。
     * @param newPassword
     */
    public void setNewPassword(String newPassword) {this.newPassword = newPassword;}
    /**
     * 新しいパスワードを取得する。
     * @param newPassword
     */
    public String getNewPassword() {return newPassword;}
    /**
     * 入力チェックエラーコードを取得する
     * @return errorCode
     */
    public String getErrorCode(){
        return this.errorCode;
    }
    /**
     * ユーザーIDを取得する
     * @return userID
     */
    public String getUserID(){return this.userID;}
}
